package com.kevis.zhunblog.admin.security.service;

import com.kevis.zhunblog.core.entities.PowerMenuEntity;
import com.kevis.zhunblog.mapper.RolePowerMapper;
import com.kevis.zhunblog.service.PowerMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Set;

/**
 * SecurityMetadataSource
 * 每一次请求都会调用这个数据源
 * 这里主要提供该链接对应用户所拥有的权限是什么，存进去
 *
 * @Author kevis
 * @Date 2023/3/31 10:22
 */
@Component
public class SecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Resource
    private RolePowerMapper rolePowerMapper;

    @Autowired
    private PowerMenuService powerMenuService;

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
//        String requestURI = ((FilterInvocation) object).getRequest().getRequestURI();//getServletPath()
        String servletPath = ((FilterInvocation) object).getRequest().getServletPath();//getServletPath()
        //这边的地址要做 XXS安全处理(如html js标签等)，防止别人乱写地址导致查询时候被SQL注入之类
        servletPath = servletPath.replaceAll("'", "").substring(1);
//        if ("login" .equalsIgnoreCase(servletPath)) {
//            return null;
//        }
        //改造了使用 zhun/post.do 的地址
        String ActionGuid = ((FilterInvocation) object).getRequest().getParameter("actionguid");
//        if (!StringUtils.hasLength(ActionGuid)) {
//            return SecurityConfig.createList("9999");
//        }
        //先要判断这个菜单是否在菜单表,在的话，说明需要进行权限控制。不在说明可能是静态资源等不需要权限控制的
        //boolean isExistsPowerMenu = powerMenuService.existsByUrl(servletPath);
        //查询进入到此的地址,是否存在,不存在一律403,存在就继续判断是否有权限.因为地址是统一的 /zhun/post.do ,如果绕过直接访问真实地址,但是没做控制就会直接访问了
        PowerMenuEntity powerMenuEntity = powerMenuService.lambdaQuery().eq(PowerMenuEntity::getGuid, ActionGuid).one();
        //if(isExistsPowerMenu) {
        if (null != powerMenuEntity && powerMenuEntity.getId() > 0) {
            //根据url查询对应的 role 集合
            //Set<Integer> roleList = rolePowerMapper.getRolesByUrlMenuCode(servletPath, "list");
            Set<Integer> roleList = rolePowerMapper.getRoleByPowerId(powerMenuEntity.getId());
            if (roleList != null && roleList.size() > 0) {
                String[] roles = roleList.stream().map(r -> "ROLE_" + r.toString()).toArray(String[]::new);
                //String[] roles = roleList.stream().map(Object::toString).toArray(String[]::new);
                //return SecurityConfig.createList(String.valueOf(Arrays.asList(roles)));
                return SecurityConfig.createList(roles);
            }
            //return SecurityConfig.createList("9999");
        }
        //return null;
        return SecurityConfig.createList("9999");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
//        List<RolePowerEntity> entities = rolePowerMapper.selectList(null);
//        String[] roles = entities.stream().map(t->t.getRoleId().toString()).toArray(String[]::new);
//        return SecurityConfig.createList(String.valueOf(Arrays.asList(roles)));
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
        //return false;
    }
}
